package com.kb5173.search.index.service.impl;

import com.kb5173.framework.dataaccess.pagination.GenericPage;
import com.kb5173.framework.shared.utils.BeanMapper;
import com.kb5173.search.common.define.enums.OptionType;
import com.kb5173.search.common.define.enums.ResponseCodes;
import com.kb5173.search.common.entity.GoodsEO;
import com.kb5173.search.common.exception.IndexException;
import com.kb5173.search.common.exception.QueryException;
import com.kb5173.search.index.dao.IExpireIndexIdRedisDAO;
import com.kb5173.search.index.document.BaseIndexDocument;
import com.kb5173.search.index.document.GoodsDocument;
import com.kb5173.search.index.service.IIndexService;
import com.kb5173.search.index.utils.BeanToMapUtil;
import com.kb5173.search.index.utils.DocumentUtil;
import com.kb5173.search.index.utils.PageTransformUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.*;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Chengfei.Sun
 */
@Component
public class IndexServiceImpl implements IIndexService {
    @Autowired
    SolrTemplate solrTemplate;

    @Autowired
    IExpireIndexIdRedisDAO expireIndexIdRedisDAO;

    @Override
    public GenericPage<GoodsEO> search(String gameName, String gameArea, String gameServer, String type,
                                       String keyword, Integer pageSize, Integer pageNub) {
        if (StringUtils.isEmpty(keyword)) {
            throw new QueryException(ResponseCodes.EmptyKeyWords.getCode());
        }

        Query query = new SimpleQuery();

        keyword = keyword.replace(" ", "");
        query.addCriteria(new Criteria(GoodsDocument.TITLE_FIELD).is(keyword).boost(80).
                or(new Criteria("text").is(keyword).boost(50)));

        if (StringUtils.isNotEmpty(type)) {
            query.addCriteria(new Criteria(BaseIndexDocument.Document_TYPE_FIELD).is(type));
        }
        if (StringUtils.isNotEmpty(gameName)) {
            query.addCriteria(new Criteria(GoodsDocument.GAME_NAME_FIELD).is(gameName));
        }
        if (StringUtils.isNotEmpty(gameArea)) {
            query.addCriteria(new Criteria(GoodsDocument.GAME_AREA_FIELD).is(gameArea));
        }
        if (StringUtils.isNotEmpty(gameServer)) {
            query.addCriteria(new Criteria(GoodsDocument.GAME_SERVER_FIELD).is(gameServer));
        }

        if (query.getCriteria() == null) {
            query.addCriteria(new SimpleStringCriteria("*:*"));
        }
        // 默认页码为1，页面大小为10
        if (pageNub == null || pageNub <= 0) {
            pageNub = 1;
        }
        if (pageSize == null || pageSize <= 0) {
            pageSize = 10;
        }

        PageRequest pagebale = new PageRequest(pageNub - 1, pageSize);
        query.setPageRequest(pagebale);

        Page<GoodsDocument> result = solrTemplate.queryForPage(query, GoodsDocument.class);

        return PageTransformUtil.covertPage(result);
    }

    @Override
    public void optionDocument(Integer optionType, GoodsEO goodsEO) {
        if(optionType == null){
            throw new IndexException(ResponseCodes.EmptyOptionType.getCode());
        }
        if (StringUtils.isEmpty(goodsEO.getOfferno())) {
            throw new IndexException(ResponseCodes.EmptyOfferno.getCode());
        }
        if (StringUtils.isEmpty(goodsEO.getType())) {
            throw new IndexException(ResponseCodes.EmptyType.getCode());
        }

        // 根据optionType，调用相应的索引操作
        OptionType optionEnum = OptionType.getTypeByValue(optionType);
        switch (optionEnum) {
            case Insert:
                this.saveDocument(goodsEO);
                break;
            case Update:
                this.updateDocument(goodsEO);
                break;
            case Delete:
                List<String> indexIds = new ArrayList<String>();
                indexIds.add(DocumentUtil.geneIndexId(goodsEO));
                this.deleteDocumentByIds(indexIds);
                break;
        }
    }

    @Override
    public void saveDocument(GoodsEO goodsEO) {
        if (StringUtils.isEmpty(goodsEO.getType())) {
            throw new IndexException(ResponseCodes.EmptyType.getCode());
        }
        if(StringUtils.isEmpty(goodsEO.getSource())){
            throw new IndexException(ResponseCodes.EmptySource.getCode());
        }
        if (StringUtils.isEmpty(goodsEO.getOfferno())) {
            throw new IndexException(ResponseCodes.EmptyOfferno.getCode());
        }
        if (StringUtils.isEmpty(goodsEO.getGameName())) {
            throw new IndexException(ResponseCodes.EmptyGameName.getCode());
        }
        if (StringUtils.isEmpty(goodsEO.getGameArea())) {
            throw new IndexException(ResponseCodes.EmptyGameArea.getCode());
        }
        if (StringUtils.isEmpty(goodsEO.getGameServer())) {
            throw new IndexException(ResponseCodes.EmptyGameServer.getCode());
        }
        if (StringUtils.isEmpty(goodsEO.getTitle())) {
            throw new IndexException(ResponseCodes.EmptyTitle.getCode());
        }
        if (StringUtils.isEmpty(goodsEO.getSellerid())) {
            throw new IndexException(ResponseCodes.EmptySellerId.getCode());
        }
        if (goodsEO.getUnitprice() == null || (goodsEO.getUnitprice().compareTo(BigDecimal.ZERO)) <= 0) {
            throw new IndexException(ResponseCodes.EmptyUnitPrice.getCode());
        }
        if (goodsEO.getQuantity() == null || goodsEO.getQuantity() <= 0) {
            throw new IndexException(ResponseCodes.EmptyQuantity.getCode());
        }
        if(goodsEO.getExpireddate() == null){
            throw new IndexException(ResponseCodes.EmptyExpireDate.getCode());
        }
        if(StringUtils.isEmpty(goodsEO.getUnitname())){
            throw new IndexException(ResponseCodes.EmptyUnitPrice.getCode());
        }
        GoodsDocument goodsDocument = BeanMapper.map(goodsEO, GoodsDocument.class);
        String indexId = DocumentUtil.geneIndexId(goodsEO); // 生成索引Id
        goodsDocument.setIndexId(indexId);
        solrTemplate.saveBean(goodsDocument);
        solrTemplate.softCommit();

        //添加过期index
        expireIndexIdRedisDAO.addExpireId(indexId, goodsEO.getExpireddate());
    }

    @Override
    public void updateDocument(GoodsEO goodsEO) {
        if (StringUtils.isEmpty(goodsEO.getOfferno())) {
            throw new IndexException(ResponseCodes.EmptyOfferno.getCode());
        }
        if (StringUtils.isEmpty(goodsEO.getType())) {
            throw new IndexException(ResponseCodes.EmptyType.getCode());
        }

        String indexId = DocumentUtil.geneIndexId(goodsEO);
        PartialUpdate partialUpdate = BeanToMapUtil.convertSrData(goodsEO, indexId);
        solrTemplate.saveBean(partialUpdate);
        solrTemplate.softCommit();

        //修改过期index
        if(goodsEO.getExpireddate() != null){
            expireIndexIdRedisDAO.addExpireId(indexId, goodsEO.getExpireddate());
        }
    }

    @Override
    public void deleteDocumentByIds(List<String> indexIdList) {
        if (indexIdList == null || indexIdList.size() == 0) {
            throw new IndexException(ResponseCodes.EmptyIndexId.getCode());
        }

        solrTemplate.deleteById(indexIdList);
        solrTemplate.softCommit();
    }
}
